package online.inote.naruto.common.global;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import online.inote.naruto.common.utils.response.Code;
import online.inote.naruto.common.utils.response.ExtendResponse;
import online.inote.naruto.common.utils.response.Response;
import online.inote.naruto.utils.log.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;

/**
 * @description 返回信息处理
 * @author XQF.Sui
 * @date 2019/10/21 3:19 下午
 * @version 1.0
 */
public class GlobalResultHandle {

  private static LoggerFactory log =
      LoggerFactory.getLogger(GlobalResultHandle.class).module("GlobalResultHandle");

  @RestControllerAdvice("cn.creditease")
  static class CommonResultResponseAdvice implements ResponseBodyAdvice<Object> {
    @Override
    public boolean supports(
        MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
      return true;
    }

    /**
     * @description 重写请求后的返回结果
     * @author XQF.Sui
     * @date 2019/10/24 11:31 上午
     * @param： [body, methodParameter, mediaType, aClass, serverHttpRequest, serverHttpResponse]
     * @return java.lang.Object
     */
    @Override
    public Object beforeBodyWrite(
        Object body,
        MethodParameter methodParameter,
        MediaType mediaType,
        Class<? extends HttpMessageConverter<?>> aClass,
        ServerHttpRequest serverHttpRequest,
        ServerHttpResponse serverHttpResponse) {
      return initResult(body);
    }

    @ExceptionHandler(value = Exception.class)
    public Object exceptionHandle(HttpServletRequest request, Exception e) {
      return initResult(ExtendResponse.fail(e.getMessage()));
    }

    private static Object initResult(Object body) {
      if (body instanceof Response) {
        return body;
      }

      if (body instanceof String) {
        try {
          JSONObject o = JSON.parseObject(body.toString());

          if (o.containsKey(Response.Fields.code) && o.containsKey(Response.Fields.message)) {
            return body;
          }
        } catch (Exception e) {
          log.error().message("body conversion failed.").throwable(e).print();
        }
      }

      return Response.create(Code.SUCCESS.getCode(), null, body);
    }
  }
}
